-
Notifications
You must be signed in to change notification settings - Fork 29.6k
New issue
Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.
By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.
Already on GitHub? Sign in to your account
src: add Atomics.notify alias #21413
Conversation
test/parallel/test-atomics-notify.js
Outdated
|
||
const { strictEqual } = require('assert'); | ||
|
||
strictEqual(Atomics.notify, Atomics.wake); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
maybe add a test for vm
as well?
ee6efd2
to
f99a3ea
Compare
To prevent any sort of hazard, I wonder if Atomics.notify should be preserved if it already exists from V8, this way it's not necessary to clone anything from Atomics.wake. |
@leobalter when we update v8 to a version that has Atomics.notify we can just remove this change. i would prefer that actually so we don't have dead code hanging around. |
@devsnek I'm a newbie wrt node ecosystem, if this can be done, I'm +1. Having Atomics.notify here is great anyway. |
Does this actually help with the issue raised in #21219 if
At least if I go to MDN to look for docs I'll still see |
context->SetEmbedderData( | ||
ContextEmbedderIndex::kAllowWasmCodeGeneration, True(isolate)); | ||
|
||
auto intl_key = FIXED_ONE_BYTE_STRING(isolate, "Intl"); |
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
Is there a reason these lines got moved?
There was a problem hiding this comment.
Choose a reason for hiding this comment
The reason will be displayed to describe this comment to others. Learn more.
just a side-effect of the changes i was making before i finished up. should i change it back? they kinda make the order better anyway.
@joyeecheung i wanted to add warnings and stuff but since we have to do it in c++ i don't know how viable it is. maybe we could move the intl and atomics stuff into a js file somewhere that's only called when making a new context. iirc v8_extras also run per-context so those could help too. |
@nodejs/v8 out of curiosity i tried to implement this with v8 extras but any attempt to access or set properties on |
Do you have any backtrace from a debug build? I suspect that some external references are missing. |
@hashseed i don't have the power atm to fully recompile with debug but i've got
also running mksnapshot (which iirc should show a help message?):
|
I think you introduced some code that caused bootstrapping (creating a context from scratch) to fail. It then returns an empty handle, so that using it as a default context in the snapshot causes a crash. |
@hashseed here's the script but the repro is as simple as https://gist.github.com/devsnek/3679af4029594f31a62b70e35ed035d9 |
That's because |
@hashseed is that the kind of thing where a flag can be flipped or do we just have to wait and use another solution for now. |
I don't think there is a good solution currently. By default, V8 ships without So at this point adding it to the snapshot is not really an option, unfortunately. |
@joyeecheung @addaleax @hashseed this works but is it a good idea? i'm having trouble weighting like the pros and cons here. the diff below lets us set the function name and warn and stuff but i don't know if it causes a slow-down to call it all on every new context created, especially since we can't create a cache for it. diff --git a/lib/internal/per_context.js b/lib/internal/per_context.js
new file mode 100644
index 0000000000..3dce7f188b
--- /dev/null
+++ b/lib/internal/per_context.js
@@ -0,0 +1,52 @@
+'use strict';
+
+// node::NewContext calls this script
+
+(function(global, binding, v8) {
+ // https://github.com/nodejs/node/issues/14909
+ delete global.Intl.v8BreakIterator;
+
+ // https://github.com/nodejs/node/issues/21219
+ // Adds Atomics.notify and warns on first usage of Atomics.wake
+
+ const AtomicsWake = global.Atomics.wake;
+ const ReflectApply = global.Reflect.apply;
+
+ // wrap for function.name
+ function notify(...args) {
+ return ReflectApply(AtomicsWake, this, args);
+ }
+
+ const warning = 'Atomics.wake will be removed in a future version, ' +
+ 'use Atomics.notify instead.';
+
+ let wakeWarned = false;
+ function wake(...args) {
+ if (!wakeWarned) {
+ wakeWarned = true;
+
+ if (global.process !== undefined) {
+ global.process.emitWarning(warning, 'Atomics');
+ } else {
+ global.console.error(`Atomics: ${warning}`);
+ }
+ }
+
+ return ReflectApply(AtomicsWake, this, args);
+ }
+
+ global.Object.defineProperties(global.Atomics, {
+ notify: {
+ value: notify,
+ enumerable: false,
+ configurable: true,
+ writable: true,
+ },
+ wake: {
+ value: wake,
+ enumerable: false,
+ configurable: true,
+ writable: true,
+ },
+ });
+}(this));
diff --git a/node.gyp b/node.gyp
index 301a0e20a1..4f70ee5f29 100644
--- a/node.gyp
+++ b/node.gyp
@@ -24,6 +24,7 @@
'node_lib_target_name%': 'node_lib',
'node_intermediate_lib_type%': 'static_library',
'library_files': [
+ 'lib/internal/per_context.js',
'lib/internal/bootstrap/loaders.js',
'lib/internal/bootstrap/node.js',
'lib/async_hooks.js',
diff --git a/src/node.cc b/src/node.cc
index 6cf5f2ad84..70c5a132cc 100644
--- a/src/node.cc
+++ b/src/node.cc
@@ -3478,35 +3478,21 @@ Local<Context> NewContext(Isolate* isolate,
auto context = Context::New(isolate, nullptr, object_template);
if (context.IsEmpty()) return context;
HandleScope handle_scope(isolate);
+
context->SetEmbedderData(
ContextEmbedderIndex::kAllowWasmCodeGeneration, True(isolate));
- auto intl_key = FIXED_ONE_BYTE_STRING(isolate, "Intl");
- auto break_iter_key = FIXED_ONE_BYTE_STRING(isolate, "v8BreakIterator");
- Local<Value> intl_v;
- if (context->Global()->Get(context, intl_key).ToLocal(&intl_v) &&
- intl_v->IsObject()) {
- Local<Object> intl = intl_v.As<Object>();
- intl->Delete(context, break_iter_key).FromJust();
- }
-
- // https://github.com/nodejs/node/issues/21219
- // TODO(devsnek): remove when v8 supports Atomics.notify
- auto atomics_key = FIXED_ONE_BYTE_STRING(isolate, "Atomics");
- Local<Value> atomics_v;
- if (context->Global()->Get(context, atomics_key).ToLocal(&atomics_v) &&
- atomics_v->IsObject()) {
- Local<Object> atomics = atomics_v.As<Object>();
- auto wake_key = FIXED_ONE_BYTE_STRING(isolate, "wake");
-
- Local<Value> wake = atomics->Get(context, wake_key).ToLocalChecked();
- auto notify_key = FIXED_ONE_BYTE_STRING(isolate, "notify");
-
- v8::PropertyDescriptor desc(wake, true);
- desc.set_enumerable(false);
- desc.set_configurable(true);
-
- atomics->DefineProperty(context, notify_key, desc).ToChecked();
+ {
+ // Run lib/internal/per_context.js
+ Context::Scope context_scope(context);
+ Local<String> per_context = NodePerContextSource(isolate);
+ v8::ScriptCompiler::Source per_context_src(per_context, nullptr);
+ Local<v8::Script> s = v8::ScriptCompiler::Compile(
+ context,
+ &per_context_src,
+ v8::ScriptCompiler::kNoCompileOptions,
+ v8::ScriptCompiler::kNoCacheBecauseCachingDisabled).ToLocalChecked();
+ s->Run(context).ToLocalChecked();
}
return context;
diff --git a/src/node.h b/src/node.h
index 90b2a8cbf6..b551c8bb09 100644
--- a/src/node.h
+++ b/src/node.h
@@ -241,9 +241,7 @@ class MultiIsolatePlatform : public v8::Platform {
// Creates a new isolate with Node.js-specific settings.
NODE_EXTERN v8::Isolate* NewIsolate(ArrayBufferAllocator* allocator);
-// Creates a new context with Node.js-specific tweaks. Currently, it removes
-// the `v8BreakIterator` property from the global `Intl` object if present.
-// See https://github.com/nodejs/node/issues/14909 for more info.
+// Creates a new context with Node.js-specific tweaks.
NODE_EXTERN v8::Local<v8::Context> NewContext(
v8::Isolate* isolate,
v8::Local<v8::ObjectTemplate> object_template =
diff --git a/src/node_javascript.h b/src/node_javascript.h
index d1ad9a2574..00cdc0c0b6 100644
--- a/src/node_javascript.h
+++ b/src/node_javascript.h
@@ -29,6 +29,7 @@
namespace node {
void DefineJavaScript(Environment* env, v8::Local<v8::Object> target);
+v8::Local<v8::String> NodePerContextSource(v8::Isolate* isolate);
v8::Local<v8::String> LoadersBootstrapperSource(Environment* env);
v8::Local<v8::String> NodeBootstrapperSource(Environment* env);
diff --git a/tools/js2c.py b/tools/js2c.py
index 38cf39f816..249df58085 100755
--- a/tools/js2c.py
+++ b/tools/js2c.py
@@ -189,6 +189,10 @@ namespace {{
}} // anonymous namespace
+v8::Local<v8::String> NodePerContextSource(v8::Isolate* isolate) {{
+ return internal_per_context_value.ToStringChecked(isolate);
+}}
+
v8::Local<v8::String> LoadersBootstrapperSource(Environment* env) {{
return internal_bootstrap_loaders_value.ToStringChecked(env->isolate());
}} |
@devsnek I’d stick to the current approach for this PR Also, if you want to pursue the extras approach for later, maybe have a look at ayojs/ayo@84fc9ce ? /cc @TimothyGu |
this needs another approval |
@joyeecheung I'm on the MDN-PAB and moderate all the JS docs :) I started planning for the Atomics.wake => Atomics.notify docs change/update earlier this week. |
@hashseed re:
I'm not sure I understand this, but that's likely because I missing some important context. If V8 wasn't shipping $ nvm use 8
Now using node v8.11.3 (npm v5.6.0)
$ node -e "console.log(process.versions.v8);"
6.2.414.54
$ node -e "console.log(Atomics.wake);"
[Function: wake]
$ nvm use 10
Now using node v10.5.0 (npm v6.1.0)
$ node -e "console.log(process.versions.v8);"
6.7.288.46-node.8
$ node -e "console.log(Atomics.wake);"
[Function: wake]
Again, I think I'm missing some important context, so please correct as necessary—but (Also, I noted just now that you were the last person to commit to that file!) |
@rwaldron so basically since Atomics can be disabled at runtime (i'm not sure on the defaults there) they can't make memory snapshots that use Atomics because it might not exist, in which case the snapshot is invalid. i do agree that i'm confused about atomics being disabled by default, as i think its the other way around. |
Yup. What @devsnek said. |
landed in 84f3769 |
|
Notable changes: * build: * Node.js should now be about 60% faster to startup than the previous version, thanks to the use V8's code cache feature for core modules. [#21405](#21405) * dns: * An experimental promisified version of the dns module is now available. Give it a try with `require('dns').promises`. [#21264](#21264) * fs: * `fs.lchown` has been undeprecated now that libuv supports it. [#21498](#21498) * lib: * `Atomics.wake` is being renamed to `Atomics.notify` in the ECMAScript specification ([reference](tc39/ecma262#1220)). Since Node.js now has experimental support for worker threads, we are being proactive and added a `notify` alias, while emitting a warning if `wake` is used. [#21413](#21413) [#21518](#21518) * n-api: * Add API for asynchronous functions. [#17887](#17887) * util: * `util.inspect` is now able to return a result instead of throwing when the maximum call stack size is exceeded during inspection. [#20725](#20725) * vm: * Add `script.createCachedData()`. This API replaces the `produceCachedData` option of the `Script` constructor that is now deprecated. [#20300](#20300) * worker: * Support for relative paths has been added to the `Worker` constructor. Paths are interpreted relative to the current working directory. [#21407](#21407) PR-URL: #21629
Notable changes: * dns: * An experimental promisified version of the dns module is now available. Give it a try with `require('dns').promises`. [#21264](#21264) * fs: * `fs.lchown` has been undeprecated now that libuv supports it. [#21498](#21498) * lib: * `Atomics.wake` is being renamed to `Atomics.notify` in the ECMAScript specification ([reference](tc39/ecma262#1220)). Since Node.js now has experimental support for worker threads, we are being proactive and added a `notify` alias, while emitting a warning if `wake` is used. [#21413](#21413) [#21518](#21518) * n-api: * Add API for asynchronous functions. [#17887](#17887) * util: * `util.inspect` is now able to return a result instead of throwing when the maximum call stack size is exceeded during inspection. [#20725](#20725) * vm: * Add `script.createCachedData()`. This API replaces the `produceCachedData` option of the `Script` constructor that is now deprecated. [#20300](#20300) * worker: * Support for relative paths has been added to the `Worker` constructor. Paths are interpreted relative to the current working directory. [#21407](#21407) PR-URL: #21629
Notable changes: * dns: * An experimental promisified version of the dns module is now available. Give it a try with `require('dns').promises`. [#21264](#21264) * fs: * `fs.lchown` has been undeprecated now that libuv supports it. [#21498](#21498) * lib: * `Atomics.wake` is being renamed to `Atomics.notify` in the ECMAScript specification ([reference](tc39/ecma262#1220)). Since Node.js now has experimental support for worker threads, we are being proactive and added a `notify` alias, while emitting a warning if `wake` is used. [#21413](#21413) [#21518](#21518) * n-api: * Add API for asynchronous functions. [#17887](#17887) * util: * `util.inspect` is now able to return a result instead of throwing when the maximum call stack size is exceeded during inspection. [#20725](#20725) * vm: * Add `script.createCachedData()`. This API replaces the `produceCachedData` option of the `Script` constructor that is now deprecated. [#20300](#20300) * worker: * Support for relative paths has been added to the `Worker` constructor. Paths are interpreted relative to the current working directory. [#21407](#21407) PR-URL: #21629
Refs: #21219
/cc @rwaldron
Checklist
make -j4 test
(UNIX), orvcbuild test
(Windows) passes